package replication;

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.InetAddress;
import java.net.Socket;
import java.util.HashMap;
import java.util.List;
import java.util.logging.FileHandler;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

import javolution.util.FastList;
import beans.*;

public class Replicator extends Thread{
	
	public static Logger log = Logger.getLogger("log_file");
	 FileHandler hand;

	private List<String>listHosts;
	private int port=9999;
	//Context
	private FastList<Serializable>FileBA;
	private FastList<Serializable>FileLV;
	private FastList<Serializable>FileMY;
	private FastList<Serializable>FileNC;
	
	public Replicator() {
		FileBA=new FastList<Serializable>();
		FileLV=new FastList<Serializable>();
		FileMY=new FastList<Serializable>();
		FileNC=new FastList<Serializable>();
	}
	
	public Replicator(int port,List<String> listHosts) {
		this.port=port;
		this.listHosts = listHosts;
		FileBA=new FastList<Serializable>();
		FileLV=new FastList<Serializable>();
		FileMY=new FastList<Serializable>();
		FileNC=new FastList<Serializable>();
	}
	
	public void setListHosts(List<String> listHosts) {
		this.listHosts = listHosts;
		System.out.println(listHosts.get(0));
	}
	
	public void run(){
		try {
			try {
				hand = new FileHandler("MonLog.txt");
				log.addHandler(hand);
				SimpleFormatter formatter=new SimpleFormatter();
				hand.setFormatter(formatter);
			} catch (SecurityException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			while(true){
				sleep(5000);
				replicate();
			}
		} catch (Exception e) {
			// TODO: handle exception
		}
	}
	
	public void replicate(){
		log.info("==> Replication démarrée");
		for (int i = 0; i < listHosts.size(); i++) {
			
			notify_NewContext(listHosts.get(i));
			
			replicateList(listHosts.get(i), FileBA);
			
			notify_NextQueue(listHosts.get(i));
			replicateList(listHosts.get(i), FileMY);
			
			notify_NextQueue(listHosts.get(i));
			replicateList(listHosts.get(i), FileLV);
			
			notify_NextQueue(listHosts.get(i));
			replicateList(listHosts.get(i), FileNC);
			
			notify_EndContext(listHosts.get(i));
		}
	}

	private void notify_EndContext(String host) {
		// TODO Auto-generated method stub
		Socket socket = null;
		ObjectOutputStream oo ;
		try {
			socket = new Socket(InetAddress.getByName(host), port);
			oo = new ObjectOutputStream(socket.getOutputStream());
			oo.writeObject(new EndContext());
			oo.flush();  
			System.out.println("ici ça passe ?");
		} catch (Exception e) {
			// TODO: handle exception
		}
	}

	public void replicateList(String host,FastList<Serializable>myList){
		Socket socket = null;
		ObjectOutputStream oo ;
		try {
			  for (int i = 0; i < myList.size(); i++) {
					socket = new Socket(InetAddress.getByName(host), port);
					oo = new ObjectOutputStream(socket.getOutputStream());
					oo.writeObject(myList.get(i));
					oo.flush();      
		      }
					      
	    	}catch(Exception ex){
	    		ex.printStackTrace();
	    	}
	}
	
	public void notify_NewContext(String host){
		Socket socket = null;
		ObjectOutputStream oo ;
		try {
			socket = new Socket(InetAddress.getByName(host), port);
			oo = new ObjectOutputStream(socket.getOutputStream());
			oo.writeObject(new NewContext());
			oo.flush();  
			System.out.println("ici ça passe ?");
		} catch (Exception e) {
			// TODO: handle exception
		}
	}
	
	public void notify_NextQueue(String host){
		Socket socket = null;
		ObjectOutputStream oo ;
		try {
			socket = new Socket(InetAddress.getByName(host), port);
			oo = new ObjectOutputStream(socket.getOutputStream());
			oo.writeObject(new NextQueue());
			oo.flush();      
		} catch (Exception e) {
			// TODO: handle exception
		}
	}
	
	
	//Getters and Setters
	
	public FastList<Serializable> getFileBA() {
		return FileBA;
	}

	public void setFileBA(FastList<Serializable> fileBA) {
		FileBA = fileBA;
	}

	public FastList<Serializable> getFileLV() {
		return FileLV;
	}

	public void setFileLV(FastList<Serializable> fileLV) {
		FileLV = fileLV;
	}

	public FastList<Serializable> getFileMY() {
		return FileMY;
	}

	public void setFileMY(FastList<Serializable> fileMY) {
		FileMY = fileMY;
	}

	public FastList<Serializable> getFileNC() {
		return FileNC;
	}

	public void setFileNC(FastList<Serializable> fileNC) {
		FileNC = fileNC;
	}

	public List<String> getListHosts() {
		return listHosts;
	}

}
